﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Dycox.Validation;

namespace Dycox.Workflows.Conditions
{
    public abstract class PropertyValueCondition : ValidatorBasedCondition
    {
        public PropertyValueCondition(Dictionary<string, string> parameters)
            : base()
        {
            this.PropertyName = parameters["property"];
        }

        Validator _validator;

        protected override Validation.Validator Validator
        {
            get
            {
                if (_validator == null)
                {
                    _validator = this.CreateInnerValidator();
                    _validator.Validating += _validator_Validating;
                }
                return _validator;
            }
        }

        void _validator_Validating(object sender, ValidationEventArgs e)
        {
            InitializeInnerValidator(_validator, e.ValueToValidate);
        }

        protected abstract Validator CreateInnerValidator();

        protected virtual void InitializeInnerValidator(Validator validator, object valueToValidate)
        {
        }

        protected override object GetValidationValue(ConditionTestArguments args)
        {
            object value = Utils.DataBinderUtil.Eval(args, PropertyName);

            return value;// Dycox.Utils.DataBinderUtil.Eval(container, _propertyName);
        }

        //private void ParsePropertyName(string propertyName)
        //{
            //string expression = propertyName;

            //int p0 = expression.IndexOf("::");
            //string containerName;
            //bool isStageName = false;

            //if (p0 >= 0)
            //{
            //    containerName = expression.Substring(0, p0);
            //    expression = expression.Substring(p0 + 1);
            //    if (containerName.Length > 1 && containerName[0] == StageNameIndicator)
            //    {
            //        isStageName = true;
            //        containerName = containerName.Substring(1);
            //    }
            //}
            //else
            //{
            //    containerName = null;
            //}

            //if (string.IsNullOrWhiteSpace(expression))
            //    throw new ArgumentException("Invalid property name " + propertyName);

            //_contextName = containerName;
            //_expression = expression;
            //_isStageName = isStageName;

        //}


        //private string _contextName;
        //private string _expression;

        //protected object GetPropertyValue(ConditionTestArguments args)
        //{
        //    object container;
        //    string expression;

        //    if (ParsePropertyName(args, out container, out expression))
        //    {
        //        object value;

        //        try { value = Dycox.Utils.DataBinderUtil.Eval(container, expression); }
        //        catch { value = null; }

        //        return value;
        //    }
        //    else
        //        return null;
        //}

        //protected Type GetPropertyType(ConditionTestArguments args)
        //{
        //    object value = GetPropertyValue(args);
        //    if (value != null) return value.GetType();
        //    else return null;
        //}

        private string _propertyName;

        public string PropertyName
        {
            get
            {
                if (_propertyName == null)
                    throw new InvalidOperationException("PropertyName property not specified.");

                return _propertyName;
            }
            private set
            {
                if (string.IsNullOrEmpty(value))
                    throw new ArgumentNullException("PropertyName");
                //ParsePropertyName(value);
                _propertyName = value;
            }
        }

        protected internal override void PopulateDependentProperties(List<string> list)
        {
            list.Add(PropertyName);
        }
    }
}
